use rand::distributions::{Alphanumeric, Distribution};

pub struct PasswordUtils {}

impl PasswordUtils {
    pub fn encode(raw_password: &str, salt: &str) -> String {
        let mut raw = String::new();
        raw.push_str(raw_password);
        raw.push_str(salt);
        let digest = md5::compute(raw);
        format!("{:x}", digest)
    }

    pub fn verify(password: &str, raw_password: &str, salt: &str) -> bool {
        password.eq(&PasswordUtils::encode(raw_password, salt))
    }

    pub fn create_salt() -> String {
        let mut rng = rand::thread_rng();
        let s: String = Alphanumeric
            .sample_iter(&mut rng)
            .take(4)
            .map(char::from)
            .collect::<String>()
            .to_uppercase();
        println!("{s}");
        s
    }
}

#[cfg(test)]
mod test {
    use crate::utils::password_utils::PasswordUtils;

    #[test]
    fn test_encode() {
        let s = PasswordUtils::encode("123456", "ancd");
        println!("{:?}", s);
        assert_eq!(
            PasswordUtils::encode("123456", "ancd"),
            PasswordUtils::encode("123456", "ancd")
        )
    }

    #[test]
    fn test_salt() {
        let salt = PasswordUtils::create_salt();
        println!("{:?}", salt)
    }
}
